package com.thinkfit.jy.serialport;


import com.common.lib.manager.DataManager;

public class SportCalculateManager {

    private static final String TAG = "SportCalculateManager";

    private static SportCalculateManager mSportCalculateManager;

    private int mTimer;   //时间
    private int mDistance;  //距离
    private int mCalorie;  //卡路里
    private int mCounter;  //次数
    private int mSensorCounter;
    private int cur_speed;  //速度
    private int cur_resistance;  //阻力
    private int cur_incline;//坡度
    private int cur_rpm;  //频率
    private int cur_heartrate;  //心跳
    private int cur_power;  //功率
    private int cur_error;
    private int mH;
    private int mF;
    private int PARAMETER_ONE_KM_CAL_MIN = 16600;
    private int PARAMETER_ONE_KM_CAL_MAX = 54600;
    private int PARAMETER_SIXTY_RPM_SPEED = 19020;
    private int RESIS_LEVEL_MIN = 1;
    private int RESIS_LEVEL_MAX = 32;

    private int ONE_CYCLE_MM = PARAMETER_SIXTY_RPM_SPEED * 1000 / 3600;
    private int ONE_KM_MJ_MIN = PARAMETER_ONE_KM_CAL_MIN * 4186;
    private int ONE_KM_MJ_MAX = PARAMETER_ONE_KM_CAL_MAX * 4186;

    public static SportCalculateManager getInstance() {
        if (mSportCalculateManager == null) {
            synchronized (TAG) {
                if (mSportCalculateManager == null) {
                    mSportCalculateManager = new SportCalculateManager();
                }
            }
        }
        return mSportCalculateManager;
    }

    private SportCalculateManager() {
        algorithm_init();
    }

    private void algorithm_init() {
        mH = 1;
        mF = 0;
        cur_resistance = RESIS_LEVEL_MIN;
        algorithm_reset_data(1);
    }

    private void algorithm_reset_data(int reset_rpm_speed) {
        mTimer = 0;
        mDistance = 0;
        mCalorie = 0;
        mCounter = 0;
        mSensorCounter = 0;
        cur_incline = 0;
        if (reset_rpm_speed == 1) {
            cur_speed = 0;
            cur_rpm = 0;
        }
        cur_heartrate = 0;
        cur_power = 0;
        cur_error = 0;
    }

    public void algorithm_timer_add() {
        ++mTimer;
    }

    public void algorithm_set_error(int err_num) {
        int last_error = 0;

        if (err_num != 0 && last_error == 0) {
//            if (err_num == 0x03) {
//                beep_beep_enable(10);
//            } else {
//                beep_beep_enable(3);
//            }
        }
        last_error = err_num;
        cur_error = err_num;
    }

    public int algorithm_get_error() {
        return cur_error;
    }

    public void algorithm_set_cur_resistance(int v) {
        if (v >= RESIS_LEVEL_MIN && v <= RESIS_LEVEL_MAX) {
            cur_resistance = v;
        }
    }

    public int algorithm_get_cur_resistance() {
        return cur_resistance;
    }

    public void algorithm_set_cur_incline(int v) {
        cur_incline = v;
    }

    public void algorithm_set_cur_rpm(int v) {
        cur_rpm = (v / mH);

        if (v == 0) {
            cur_rpm = 0;
            cur_speed = 0;
            cur_power = 0;
        } else {
            cur_speed = (cur_rpm * ONE_CYCLE_MM * 60) / 10000; // 0.01km/h
            cur_power = (mF * cur_speed * 10) / 3600 / 4;        //%25
            if (cur_power > 10000) {
                cur_power = 10000;
            }
        }
    }

    public void algorithm_set_cur_heartrate(int v) {
        cur_heartrate = v;
    }

    public void algorithm_counter_add() {
        ++mCounter;
        algorithm_sensor_counter_add();
    }

    public void calculate(SerialPortManager.CurrentInfo info) {
        mCounter = info.count;
        mTimer = info.time;
        cur_rpm = info.rpm;
        cur_resistance = info.resistance;


        if (info.rpm == 0) {
            cur_rpm = 0;
            cur_speed = 0;
            cur_power = 0;
        } else {
            cur_speed = (cur_rpm * ONE_CYCLE_MM * 60) / 10000; // 0.01km/h
            cur_power = (mF * cur_speed * 10) / 3600 / 4;        //%25
            if (cur_power > 10000) {
                cur_power = 10000;
            }
        }
        if (info.isCountChange) {
            int mRealCounter = mCounter / mH;
            mF = ((ONE_KM_MJ_MAX - ONE_KM_MJ_MIN) / RESIS_LEVEL_MAX * (cur_resistance - RESIS_LEVEL_MIN) + ONE_KM_MJ_MIN) / 100000;
            mCalorie += (mF * ONE_CYCLE_MM) / 4186; // 0.1cal
            mDistance = mRealCounter * ONE_CYCLE_MM / 1000;
        }
        if (DataManager.Companion.getInstance().getUnit()) {  //英制单位
            info.speed = cur_speed * 62 / 100;
        } else {
            info.speed = cur_speed;
        }
        algorithm_get_sport_data(info);
        info.rpm = cur_rpm;
        info.heart = cur_heartrate;
        info.power = cur_power;
    }

    private void algorithm_sensor_counter_add() {
        int mRealCounter = 0;
        ++mSensorCounter;
        mRealCounter = mSensorCounter / mH;
        mF = ((ONE_KM_MJ_MAX - ONE_KM_MJ_MIN) / RESIS_LEVEL_MAX * (cur_resistance - RESIS_LEVEL_MIN) + ONE_KM_MJ_MIN) / 100000;
        mCalorie += (mF * ONE_CYCLE_MM) / 4186; // 0.1cal
        mDistance = mRealCounter * ONE_CYCLE_MM / 1000;
    }

    private void algorithm_get_sport_data(SerialPortManager.CurrentInfo info) {
        int mDistanceTmp = 0;
        int distance = 0;
        if (DataManager.Companion.getInstance().getUnit()) {
            mDistanceTmp = (mDistance * 62) / 100;
            if (mDistanceTmp > 32000) {
                mDistanceTmp = mDistanceTmp / 10;
                mDistanceTmp |= 0x8000;
            }
            distance = mDistanceTmp & 0xffff;
        } else {
            mDistanceTmp = mDistance;
            if (mDistanceTmp > 32000) {
                mDistanceTmp = mDistanceTmp / 10;
                mDistanceTmp |= 0x8000;
            }
            distance = mDistanceTmp & 0xffff;
        }
        int calorie = mCalorie / 1000;
        info.distance = distance;
        info.kcal = calorie;
    }


    public void algorithm_get_cur_data(SerialPortManager.CurrentInfo info) {
        if (DataManager.Companion.getInstance().getUnit()) {  //英制单位
            info.speed = cur_speed * 62 / 100;
        } else {
            info.speed = cur_speed;
        }
        info.resistance = cur_resistance;
        info.slop = cur_incline;
        info.rpm = cur_rpm;
        info.heart = cur_heartrate;
        info.power = cur_power;
    }

    public void resetSportData() {
        algorithm_init();
    }


}
